/*
 *  ConcreteNoteGeneratorSelectorTester.cpp
 *  SoundController0002
 *
 *  Created by jiro on 11/10/10.
 *  Copyright 2011 jiro music. All rights reserved.
 *
 */

#include "ConcreteNoteGeneratorSelectorTester.h"
#include "../../../sc/Tester/CustomAssert.h"
#include "../System0039.h"

namespace sc
{
namespace system0039
{
	void ConcreteNoteGeneratorSelectorTester::TestAll()
	{
		Test_Select000();
		Test_Select001();
	}

	void ConcreteNoteGeneratorSelectorTester::Test_Select000()
	{
		int repeatCount = 10000;
		::sc::hs::Sound::WaveType waveType;
		double dynamics = Note::piano;
		double harmonics = 1.0;
		double density = 1.0;
		ConcreteNote note0( waveType, dynamics, Note::A1, harmonics, Note::A2, harmonics );
		ConcreteNote note1( waveType, dynamics, Note::B1, harmonics, Note::B2, harmonics );
		ConcreteNoteGenerator generator0( density, note0.GetDuration() );
		ConcreteNoteGenerator generator1( density, note1.GetDuration() );

		generator0.AddNote( note0 );
		generator1.AddNote( note1 );

		ConcreteNoteGeneratorSelector selector;
		selector.AddGenerator( generator0, 1 );
		selector.AddGenerator( generator1, 1 );

		int countOf0 = 0;
		for ( int i = 0; i < repeatCount; i++ )
		{
			const ConcreteNoteGenerator& generator = selector.Select();
			if ( generator == generator0 )
			{
				countOf0++;
			}
			else if ( generator == generator1 )
			{
			}
			else
			{
				AssertFail();
			}
		}
		
		AssertLessOrEqual( 0.90 * ( repeatCount / 2.0 ), countOf0 );
		AssertLessOrEqual( countOf0, 1.10 * ( repeatCount / 2.0 ) );
	}

	void ConcreteNoteGeneratorSelectorTester::Test_Select001()
	{
		int repeatCount = 10000;
		::sc::hs::Sound::WaveType waveType;
		double dynamics = Note::piano;
		double harmonics = 1.0;
		double density = 1.0;
		ConcreteNote note0( waveType, dynamics, Note::A1, harmonics, Note::A2, harmonics );
		ConcreteNote note1( waveType, dynamics, Note::B1, harmonics, Note::B2, harmonics );
		ConcreteNoteGenerator generator0( density, note0.GetDuration() );
		ConcreteNoteGenerator generator1( density, note1.GetDuration() );

		generator0.AddNote( note0 );
		generator1.AddNote( note1 );

		ConcreteNoteGeneratorSelector selector;
		selector.AddGenerator( generator0, 1 );
		selector.AddGenerator( generator1, 4 );

		int countOf0 = 0;
		for ( int i = 0; i < repeatCount; i++ )
		{
			const ConcreteNoteGenerator& generator = selector.Select();
			if ( generator == generator0 )
			{
				countOf0++;
			}
			else if ( generator == generator1 )
			{
			}
			else
			{
				AssertFail();
			}
		}
		
		AssertLessOrEqual( 0.90 * ( repeatCount / 5.0 ), countOf0 );
		AssertLessOrEqual( countOf0, 1.10 * ( repeatCount / 5.0 ) );
	}
}
}
